home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / GRAPHICS / SPRite_TOOLS.ARC / c / io < prev    next >
Text File  |  1998-04-07  |  13KB  |  462 lines

  1. /****************************************************************************
  2.  *                                                                          *
  3.  * io.c                                                                     *
  4.  * ====                                                                     *
  5.  *                                                                          *
  6.  * I/O routines for image format conversion programs                        *
  7.  *                                                                          *
  8.  * Version 1.00 (13-Aug-1993)                                               *
  9.  *         1.10 (20-Aug-1993) read_struct & write_struct added              *
  10.  *         1.20 (22-Aug-1993) new endian routines added                     *
  11.  *         1.30 (23-Aug-1993) progess function added                        *
  12.  *         1.41 (13-Oct-1993) progess start & finish functions added        *
  13.  *                                                                          *
  14.  * (C) 1993 DEEJ Technology PLC                                             *
  15.  *                                                                          *
  16.  ****************************************************************************/
  17.  
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include "io.h"
  22.  
  23. #ifndef ENDIAN_MACROS
  24.  
  25. /*
  26.  * little-endian to big-endian
  27.  */
  28.  
  29. uint swap_endian(uint dword)
  30. {
  31.         return( ((dword & 0xff000000)>>24) |
  32.                 ((dword & 0x00ff0000)>>8)  |
  33.                 ((dword & 0x0000ff00)<<8)  |
  34.                 ((dword & 0x000000ff)<<24) );
  35. }
  36.  
  37. /*
  38.  * little-endian to big-endian for 16 bit words
  39.  */
  40.  
  41. ushort swap_endian_word(ushort word)
  42. {
  43.         return( ((ushort)(word & 0xff00)>>8) |
  44.                 ((ushort)(word & 0x00ff)<<8) );
  45. }
  46.  
  47. /*
  48.  * swaps endian of DWORD/WORD if type doesnot match machine type
  49.  * type is LITTLE_ENDIAN (LE) or BIG_ENDIAN (BE)
  50.  */
  51.  
  52. uint endian(int type, uint dword)
  53. {
  54.         if(type != ENDIAN_TYPE)
  55.                 return(swap_endian(dword));
  56.         else
  57.                 return(dword);
  58. }
  59.  
  60. ushort endian_w(int type, ushort word)
  61. {
  62. printf("endian_w in  %02X\n",word);
  63.         if(type != ENDIAN_TYPE)
  64.                 return(swap_endian_word(word));
  65.         else
  66.                 return(word);
  67. }
  68.  
  69. /*
  70.  * reverses bit fields in byte
  71.  */
  72.  
  73. uint bit_swap(uint byte)
  74. {
  75.         return( ((byte & 0x80)>>7) |
  76.                 ((byte & 0x40)>>5) |
  77.                 ((byte & 0x20)>>3) |
  78.                 ((byte & 0x10)>>1) |
  79.                 ((byte & 0x08)<<1) |
  80.                 ((byte & 0x04)<<3) |
  81.                 ((byte & 0x02)<<5) |
  82.                 ((byte & 0x01)<<7) );
  83. }
  84.  
  85. uint bit2_swap(uint byte)
  86. {
  87.         return( ((byte & 0xC0)>>6) |
  88.                 ((byte & 0x30)>>2) |
  89.                 ((byte & 0x0C)<<2) |
  90.                 ((byte & 0x03)<<6) );
  91. }
  92.  
  93. uint bit4_swap(uint byte)
  94. {
  95.         return( ((byte & 0xF0)>>4) |
  96.                 ((byte & 0x0F)<<4) );
  97. }
  98.  
  99. #endif
  100.  
  101. /* put/get word little endian */
  102.  
  103. void fputwLE(ushort word, FILE *file)
  104. {
  105.         word = endian_w(LE,word);
  106.         fwrite((char*)&word, sizeof(ushort), 1, file);
  107. }
  108.  
  109. ushort fgetwLE(FILE *file)
  110. {
  111.         ushort word;
  112.  
  113.         word = endian_w(LE,word);
  114.         fread((char*)&word, sizeof(ushort), 1, file);
  115.  
  116.         return(word);
  117. }
  118.  
  119. /* put/get word big endian */
  120.  
  121. void fputwBE(ushort word, FILE *file)
  122. {
  123.         word = endian_w(BE,word);
  124.         fwrite((char*)&word, sizeof(ushort), 1, file);
  125. }
  126.  
  127. ushort fgetwBE(FILE *file)
  128. {
  129.         ushort word;
  130.  
  131.         word = endian_w(BE,word);
  132.         fread((char*)&word, sizeof(ushort), 1, file);
  133.  
  134.         return(word);
  135. }
  136.  
  137. /* put/get double word little endian */
  138.  
  139. void fputdLE(uint dword, FILE *file)
  140. {
  141.         dword = endian(LE,dword);
  142.         fwrite((char*)&dword, sizeof(dword), 1, file);
  143. }
  144.  
  145. uint fgetdLE(FILE *file)
  146. {
  147.         uint dword;
  148.  
  149.         dword = endian(LE,dword);
  150.         fread((char*)&dword, sizeof(dword), 1, file);
  151.  
  152.         return(dword);
  153. }
  154.  
  155. /* put/get word big endian */
  156.  
  157. void fputdBE(uint dword, FILE *file)
  158. {
  159.         dword = endian(BE,dword);
  160.         fwrite((char*)&dword, sizeof(uint), 1, file);
  161. }
  162.  
  163. uint fgetdBE(FILE *file)
  164. {
  165.         uint dword;
  166.  
  167.         dword = endian(BE,dword);
  168.         fread((char*)&dword, sizeof(uint), 1, file);
  169.  
  170.         return(dword);
  171. }
  172.  
  173. /*
  174.  * reads input, output & progress filenames from argv
  175.  * and opens streams in, out & err. If names are not
  176.  * given the streams default to stdin, stdout & stderr
  177.  *
  178.  * Can be used before arg processing if syntax is
  179.  * [-in <file>] [-out <file>] [-err <file>]. If so any parts
  180.  * found are removed from parameter list. If syntax is
  181.  * [<flags>...] [<infile> [<outfile> [<errfile]]], must be
  182.  * called after flags have been processed, and argc & argv
  183.  * ajusted to after the last flag.
  184.  */
  185.  
  186. void file_args(int argc, char **argv, FILE **in, FILE **out, FILE **err)
  187. {
  188.         char *infile, *outfile, *errfile;
  189.         int    o_argc = argc;
  190.         char **o_argv = argv;
  191.  
  192.         infile = outfile = errfile = 0;
  193.  
  194.         argc--; argv++;         /* skip program name */
  195.  
  196.         /* look for -in, -out, -err <file> */
  197.  
  198.         while(argc>0)
  199.         {
  200.             if(**argv=='-')
  201.             {
  202.                 switch( (*argv)[1] )
  203.                 {
  204.                 case 'i':
  205.                         if(strcmp(*argv, "-in")==0)
  206.                         {
  207.                                 **argv = 0;     /* clear flag from parameters */
  208.                                 argc--; argv++;
  209.                                 infile = *argv;
  210.                         }
  211.                         break;
  212.  
  213.                 case 'o':
  214.                         if(strcmp(*argv, "-out")==0)
  215.                         {
  216.                                 **argv = 0;
  217.                                 argc--; argv++;
  218.                                 outfile = *argv;
  219.                         }
  220.                         break;
  221.  
  222.                 case 'e':
  223.                         if(strcmp(*argv, "-err")==0)
  224.                         {
  225.                                 **argv = 0;
  226.                                 argc--; argv++;
  227.                                 errfile = *argv;
  228.                         }
  229.                         break;
  230.  
  231.                 default:
  232.                         break;
  233.                 }
  234.             }
  235.             /* next parameter */
  236.             argc--; argv++;
  237.         }
  238.  
  239.         /* if no filenames found try alternate syntax */
  240.  
  241.         if(infile==0 && outfile==0 && errfile==0)
  242.         {
  243.                 if(o_argc>=2 && o_argv[1][0]!='-')
  244.                 {
  245.                         infile  = o_argv[1];
  246.                         if(o_argc>=3 && o_argv[2][0]!='-')
  247.                         {
  248.                                 outfile = o_argv[2];
  249.                                 if(o_argc>=4 && o_argv[3][0]!='-')
  250.                                         errfile = o_argv[3];
  251.                         }
  252.                 }
  253.         }
  254.  
  255.         if(infile == 0)
  256.         {
  257.                 *in = stdin;
  258.         }
  259.         else
  260.         {
  261.                 if((*in = fopen(infile,"r")) == NULL)
  262.                 {
  263.                         fprintf(stderr, "Unable to open input file %s\n",
  264.                                         infile);
  265.                         exit(1);
  266.                 }
  267.                 *infile = 0; /* remove from parameter list */
  268.         }
  269.         if(outfile == 0)
  270.         {
  271.                 *out = stdout;
  272.         }
  273.         else
  274.         {
  275.                 if((*out = fopen(outfile,"w")) == NULL)
  276.                 {
  277.                         fprintf(stderr, "Unable to open output file %s\n",
  278.                                         outfile);
  279.                         exit(2);
  280.                 }
  281.                 *outfile = 0; /* remove from parameter list */
  282.         }
  283.         if(errfile == 0)
  284.         {
  285.                 *err = stderr;
  286.         }
  287.         else
  288.         {
  289.                 /*
  290.                  * open err file and ensure stderr from
  291.                  * libraries uses it as well
  292.                  */
  293.  
  294.                 if((*err = freopen(errfile,"w",stderr)) == NULL)
  295.                 {
  296.                         /* dont use stderr as it will be closed */
  297.                         fprintf(stdout, "Unable to open error file %s\n",
  298.                                         errfile);
  299.                         exit(3);
  300.                 }
  301.                 /* set no buffering of stderr file */
  302.                 setvbuf(*err, NULL, _IONBF, BUFSIZ);
  303.                 *errfile = 0; /* remove from parameter list */
  304.         }
  305. }
  306.  
  307. /*
  308.  * reads in a structure from a file
  309.  * correcting for endian'ness and arbitary alignment
  310.  *
  311.  * type    : LITTLE_ENDIAN or BIG_ENDIAN
  312.  * buffer  : structure cast to uchar*
  313.  * descrip : array of structure field sizes
  314.  *           (1=byte, 2=word, 4=dword, >4=string, -1=end of table)
  315.  * file    : file stream descriptor
  316.  */
  317.  
  318. void read_struct(int type, BYTE *buffer, int *descrip, FILE *file)
  319. {
  320.         WORD  word;
  321.         DWORD dword;
  322.  
  323.         while(*descrip != -1)
  324.         {
  325.                 switch(*descrip)
  326.                 {
  327.                 case 1:         /* byte */
  328.                         *buffer++ = fgetc(file);
  329.                         break;
  330.  
  331.                 case 2:         /* word */
  332.                         fread(&word, sizeof(WORD), 1, file);
  333.                         word = endian_w(type,word);
  334.  
  335.                         buffer = (BYTE*)
  336.                               (((int)buffer+ALIGN_WORD-1) & ~(ALIGN_WORD-1));
  337.                         memcpy(buffer, (char*)&word, sizeof(WORD));
  338.                         buffer += sizeof(WORD);
  339.                         break;
  340.  
  341.                 case 4:         /* double word */
  342.                         fread(&dword, sizeof(DWORD), 1, file);
  343.                         dword = endian(type,dword);
  344.  
  345.                         buffer = (BYTE*)
  346.                               (((int)buffer+ALIGN_DWORD-1) & ~(ALIGN_DWORD-1));
  347.                         memcpy(buffer, (char*)&dword, sizeof(DWORD));
  348.                         buffer += sizeof(DWORD);
  349.                         break;
  350.  
  351.                 default:
  352.                         if(*descrip > 0)
  353.                         {
  354.                                 fread(buffer, *descrip, 1, file);
  355.                                 buffer += *descrip;
  356.                         }
  357.                         break;
  358.                 }
  359.  
  360.                 /* description pointer */
  361.  
  362.                 descrip++;
  363.         }
  364. }
  365.  
  366. /*
  367.  * writes a structure to a file
  368.  * correcting for endian'ness and arbitary alignment
  369.  */
  370.  
  371. void write_struct(int type, BYTE *buffer, int *descrip, FILE *file)
  372. {
  373.         WORD  word;
  374.         DWORD dword;
  375.  
  376.         while(*descrip != -1)
  377.         {
  378.                 switch(*descrip)
  379.                 {
  380.                 case 1:         /* byte */
  381.                         fputc(*buffer,file);
  382.                         buffer++;
  383.                         break;
  384.  
  385.                 case 2:         /* word */
  386.                         buffer = (BYTE*)
  387.                               (((int)buffer+ALIGN_WORD-1) & ~(ALIGN_WORD-1));
  388.                         memcpy((char*)&word, buffer, sizeof(WORD));
  389.                         word = endian_w(type,word);
  390.                         fwrite(&word, sizeof(WORD), 1, file);
  391.                         buffer += sizeof(WORD);
  392.                         break;
  393.  
  394.                 case 4:         /* double word */
  395.                         buffer = (BYTE*)
  396.                               (((int)buffer+ALIGN_DWORD-1) & ~(ALIGN_DWORD-1));
  397.                         memcpy((char*)&dword, buffer, sizeof(DWORD));
  398.                         dword = endian(type,dword);
  399.                         fwrite(&dword, sizeof(DWORD), 1, file);
  400.                         buffer += sizeof(DWORD);
  401.                         break;
  402.  
  403.                 default:
  404.                         if(*descrip > 0)
  405.                         {
  406.                                 fwrite(buffer, *descrip, 1, file);
  407.                                 buffer += *descrip;
  408.                         }
  409.                         break;
  410.                 }
  411.  
  412.                 /* advance description pointer */
  413.  
  414.                 descrip++;
  415.         }
  416. }
  417.  
  418. /*
  419.  * prints banner before calls to progress()
  420.  * string should not contain newline
  421.  */
  422.  
  423. void progress_start(char *string)
  424. {
  425.         fprintf(stderr, string);
  426.     progress(0,100);
  427. }
  428.  
  429. /*
  430.  * displays progress of operation on stderr
  431.  * by printing dots every 2% of completion
  432.  * determined by value of current and max
  433.  */
  434.  
  435. void progress(int current, int max)
  436. {
  437.         static old_percent = 0;
  438.         int    percent     = (current*100)/max;
  439.         int    i;
  440.  
  441.     /* reset on for new progress indication */
  442.  
  443.     if(percent < old_percent) old_percent = 0;
  444.  
  445.         if(percent-old_percent>=2)
  446.         {
  447.                 for(i=old_percent; i<percent; i+=2)
  448.                         fputc('.', stderr);
  449.                 old_percent = percent;
  450.         }
  451. }
  452.  
  453. /*
  454.  * ensure display is correct after calls to progress()
  455.  */
  456.  
  457. void progress_finish(void)
  458. {
  459.     progress(100,100);
  460.         fprintf(stderr,"\n");
  461. }
  462.